package com.example.toy.core.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DurationFormatUtils;

import java.time.Duration;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * DurationUtils
 *
 * @author shenbing
 * @date 2021/12/21
 */
@Slf4j
public class DurationUtils {

  /**
   * 将字符串解析为时间间隔对象。如果字符串没有单位，默认为毫秒
   *
   * <p>支持以下单位： 天：d 小时：h 秒：s 毫秒：ms 纳秒：ns
   *
   * @param text
   * @return
   */
  public static Duration parseDuration(String text) {
    text = text.toLowerCase(Locale.ROOT).trim();
    if (text.isEmpty()) {
      return Duration.ZERO;
    }
    Pattern p = Pattern.compile("(\\d+)([a-zA-Z]*)");
    Matcher matcher = p.matcher(text);
    if (matcher.find()) {
      int num = Integer.parseInt(matcher.group(1));
      String unit = matcher.group(2);

      switch (unit) {
        case "ns":
          return Duration.ofNanos(num);
        case "":
          log.warn("Can not find timeunit for key's value: {}", text);
          return Duration.ofMillis(num);
        case "ms":
          return Duration.ofMillis(num);
        case "s":
          return Duration.ofSeconds(num);
        case "m":
          return Duration.ofMinutes(num);
        case "h":
          return Duration.ofHours(num);
        case "d":
          return Duration.ofDays(num);
        default:
          throw new RuntimeException("Can not parse duration of config: " + text);
      }
    }
    throw new RuntimeException("Can not parse duration of config: " + text);
  }

  /**
   * 日期转字符串，默认格式：yyyy-MM-dd HH:mm:ss
   *
   * @param date
   * @return
   */
  public static String dateToString(Date date) {
    return Optional.ofNullable(date)
        .map(it -> DateFormatUtils.format(it, "yyyy-MM-dd HH:mm:ss"))
        .orElse("");
  }

  /**
   * 毫秒值转时间间隔字符串，字符串格式：HH:mm:ss
   *
   * @param duration
   * @return
   */
  public static String durationToString(long duration) {
    return DurationFormatUtils.formatDuration(duration, "HH:mm:ss");
  }

  /**
   * 两个日期之间计算时间间隔，并转换成字符串，字符串格式：HH:mm:ss
   *
   * @param start
   * @param end
   * @return
   */
  public static String durationToString(Date start, Date end) {
    if (start == null || end == null) {
      return "";
    }
    long duration = Math.abs(start.getTime() - end.getTime());
    return durationToString(duration);
  }
}
